<?php

namespace app\staff\controller;

use app\admin\model\Staff;
use app\common\model\order\Log as orderLog;
use ba\Date;
use Throwable;
use ba\Captcha;
use ba\Random;
use app\common\model\User;
use think\facade\Validate;
use app\common\facade\Token;
use app\common\model\UserScoreLog;
use app\common\model\UserMoneyLog;
use app\common\controller\Frontend;
use app\api\validate\Account as AccountValidate;

class Account extends Frontend
{
    protected array $noNeedLogin = ['retrievePassword'];

    public function initialize(): void
    {
        parent::initialize();
    }

    public function index(){
        $user = $this->auth->getUserInfo();
        $user['staff'] = Staff::where(['user_id' => $user['id']])->find();
        $this->success('', $user);
    }

    public function overview(): void
    {
        // 本月订单
        $staff = Staff::where(['user_id' => $this->auth->id])->find();
//        9网版->10做货样板及颜色->11做货
//        4做图->5菲林->6网版->7调色->8打板
        $static = [
            "wait"=> 0,
            "prod"=> 0,
            "sub"=> 0,
        ];
        $where = [];
        $query = \app\common\model\Order::where($where);
        $query->whereMonth('ba_order.create_time');
        $where[] = ['ba_order.state', 'in', ['1', '2']];
        $where[] = ['ba_order.step', 'in', $staff->department_ids];
        $static['wait'] = $query->where($where)->hasWhere('logs', ['staff_id' => $this->auth->id])->count('*');

        $query = \app\common\model\Order::whereMonth('ba_order.create_time');
        $static['prod'] = $query->hasWhere('logs', ['staff_id' => $this->auth->id])->count('*');

        $query = \app\common\model\Order::whereMonth('ba_order.create_time');
        $static['sub'] = $query->hasWhere('logs', ['staff_id' => $this->auth->id])->count('*');
        $this->success('', $static);
    }

    /**
     * 会员资料
     * @throws Throwable
     */
    public function profile(): void
    {
        if ($this->request->isPost()) {
            $data = $this->request->only(['avatar', 'name', 'address', 'id_card', 'mobile', 'duties' ] );
            $model = $this->auth->getUser();
            $model->startTrans();
            try {
                $model->save(['nickname' => $data['name'], 'avatar' => $data['avatar']]);
                $staff = Staff::where(['user_id' => $model->id])->find();
                $staff->save(['name' => $data['name'], 'address' => $data['address'], 'id_card' => $data['id_card'], 'phone' => $data['mobile'], 'duties' => $data['duties']]);
                $model->commit();
            } catch (Throwable $e) {
                $model->rollback();
                $this->error($e->getMessage());
            }

            $this->success(__('Data updated successfully~'));
        }

        $this->success('', [
            'accountVerificationType' => get_account_verification_type()
        ]);
    }

    /**
     * 通过手机号或邮箱验证账户
     * 此处检查的验证码是通过 api/Ems或api/Sms发送的
     * 验证成功后，向前端返回一个 email-pass Token或着 mobile-pass Token
     * 在 changBind 方法中，通过 pass Token来确定用户已经通过了账户验证（用户未绑定邮箱/手机时通过账户密码验证）
     * @throws Throwable
     */
    public function verification(): void
    {
        $captcha = new Captcha();
        $params  = $this->request->only(['type', 'captcha']);
        if ($captcha->check($params['captcha'], ($params['type'] == 'email' ? $this->auth->email : $this->auth->mobile) . "user_{$params['type']}_verify")) {
            $uuid = Random::uuid();
            Token::set($uuid, $params['type'] . '-pass', $this->auth->id, 600);
            $this->success('', [
                'type'                     => $params['type'],
                'accountVerificationToken' => $uuid,
            ]);
        }
        $this->error(__('Please enter the correct verification code'));
    }

    /**
     * 修改绑定信息（手机号、邮箱）
     * 通过 pass Token来确定用户已经通过了账户验证，也就是以上的 verification 方法，同时用户未绑定邮箱/手机时通过账户密码验证
     * @throws Throwable
     */
    public function changeBind(): void
    {
        $captcha = new Captcha();
        $params  = $this->request->only(['type', 'captcha', 'email', 'mobile', 'accountVerificationToken', 'password']);
        $user    = $this->auth->getUser();

        if ($user[$params['type']]) {
            if (!Token::check($params['accountVerificationToken'], $params['type'] . '-pass', $user->id, false)) {
                $this->error(__('You need to verify your account before modifying the binding information'));
            }
        } else {
            // 验证账户密码
            if (!isset($params['password']) || $user->password != encrypt_password($params['password'], $user->salt)) {
                $this->error(__('Password error'));
            }
        }

        // 检查验证码
        if ($captcha->check($params['captcha'], $params[$params['type']] . "user_change_{$params['type']}")) {
            if ($params['type'] == 'email') {
                $validate = Validate::rule(['email' => 'require|email|unique:user'])->message([
                    'email.require' => 'email format error',
                    'email.email'   => 'email format error',
                    'email.unique'  => 'email is occupied',
                ]);
                if (!$validate->check(['email' => $params['email']])) {
                    $this->error(__($validate->getError()));
                }
                $user->email = $params['email'];
            } elseif ($params['type'] == 'mobile') {
                $validate = Validate::rule(['mobile' => 'require|mobile|unique:user'])->message([
                    'mobile.require' => 'mobile format error',
                    'mobile.mobile'  => 'mobile format error',
                    'mobile.unique'  => 'mobile is occupied',
                ]);
                if (!$validate->check(['mobile' => $params['mobile']])) {
                    $this->error(__($validate->getError()));
                }
                $user->mobile = $params['mobile'];
            }
            Token::delete($params['accountVerificationToken']);
            $user->save();
            $this->success();
        }
        $this->error(__('Please enter the correct verification code'));
    }

    public function changePassword(): void
    {
        if ($this->request->isPost()) {
            $params = $this->request->only(['oldPassword', 'newPassword']);

            if (!$this->auth->checkPassword($params['oldPassword'])) {
                $this->error(__('Old password error'));
            }

            $model = $this->auth->getUser();
            $model->startTrans();
            try {
                $validate = new AccountValidate();
                $validate->scene('changePassword')->check(['password' => $params['newPassword']]);
                $model->resetPassword($this->auth->id, $params['newPassword']);
                $model->commit();
            } catch (Throwable $e) {
                $model->rollback();
                $this->error($e->getMessage());
            }

            $this->auth->logout();
            $this->success(__('Password has been changed, please login again~'));
        }
    }

    /**
     * 积分日志
     * @throws Throwable
     */
    public function integral(): void
    {
        $limit         = $this->request->request('limit');
        $integralModel = new UserScoreLog();
        $res           = $integralModel->where('user_id', $this->auth->id)
            ->order('create_time desc')
            ->paginate($limit);

        $this->success('', [
            'list'  => $res->items(),
            'total' => $res->total(),
        ]);
    }

    /**
     * 余额日志
     * @throws Throwable
     */
    public function balance(): void
    {
        $limit      = $this->request->request('limit');
        $moneyModel = new UserMoneyLog();
        $res        = $moneyModel->where('user_id', $this->auth->id)
            ->order('create_time desc')
            ->paginate($limit);

        $this->success('', [
            'list'  => $res->items(),
            'total' => $res->total(),
        ]);
    }

    /**
     * 找回密码
     * @throws Throwable
     */
    public function retrievePassword(): void
    {
        $params = $this->request->only(['type', 'account', 'captcha', 'password']);
        try {
            $validate = new AccountValidate();
            $validate->scene('retrievePassword')->check($params);
        } catch (Throwable $e) {
            $this->error($e->getMessage());
        }

        if ($params['type'] == 'email') {
            $user = User::where('email', $params['account'])->find();
        } else {
            $user = User::where('mobile', $params['account'])->find();
        }
        if (!$user) {
            $this->error(__('Account does not exist~'));
        }

        $captchaObj = new Captcha();
        if (!$captchaObj->check($params['captcha'], $params['account'] . 'user_retrieve_pwd')) {
            $this->error(__('Please enter the correct verification code'));
        }

        if ($user->resetPassword($user->id, $params['password'])) {
            $this->success(__('Password has been changed~'));
        } else {
            $this->error(__('Failed to modify password, please try again later~'));
        }
    }

    /**
     * @return void
     */
    public function orders(): void {
        $limit = $this->request->request('limit');
        $data = $this->request->post();
        $where = [];
        // 该当前账户 操作的订单
        $staff = Staff::where(['user_id' => $this->auth->id])->find();
//        9网版->10做货样板及颜色->11做货
//        4做图->5菲林->6网版->7调色->8打板
        if($data['type'] == '1'){ // 生产中
            $where[] = ['state', 'in', ['1', '2']];
            $where[] = ['step', 'in', $staff->department_ids];
        }
        $query = \app\common\model\Order::with(['user', 'productCategory', 'logs'])
            ->where($where);
        if($data['type'] == 2){ // 历史订单
            $query->hasWhere('logs', ['staff_id' => $this->auth->id]);
        }
        $res = $query->withSearch(['key', 'date', 'cate_id'], $data)->order('id desc')
            ->paginate($limit);
        $this->success('', $res);
    }

    /**
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function orderDetail(): void {
        $no = $this->request->post('no');
        $res = \app\common\model\Order::with(['user','department','device','productCategory', 'logs'])->where(['no' => $no])->find();
        $this->success('', $res);
    }

    public function orderHandler(): void {
        $data = $this->request->post();
        $order = \app\common\model\Order::where(['no' => $data['order_no']])->findOrEmpty();
        if($order->isEmpty()){
            $this->error('未找到订单信息!');
        }
        $save_data = [
            'order_id' => $order->id,
            'staff_id' => $this->auth->id,
            'title' => '员工提交生产记录',
            'desc' => $data['desc'],
            'images' => $data['images'],
            'step' => $data['step'],
            'num' => isset($data['num']) ? $data['num'] : '' ,
            'step_label' => $data['step_label'],
        ];
        orderLog::create($save_data);
        if($data['complete'] == 1){
            //  订单流转到下一步骤
            $step_index = 0;
            foreach ($order->steps[$order->type] as $index => $v){
                if($v['id'] == $data['step']) {
                    $step_index = $index;
                    break;
                }
            }
            $next_step_index = ++$step_index;
            if(empty($order->steps[$order->type][$next_step_index])){ // 下一步骤为空 就代表当前是 生产的最后一个环节
                $order->step = 999;
                $order->state = 3;
            } else {
                $order->state = 2;
                $order->step = $order->steps[$order->type][$next_step_index]['id'];
            }
            $order->save();
        }
        $this->success('');
    }
}